import Vue from "vue";
import axios from "axios";
import router from "@/router";

import { globalVariable, ifGlobalConfigRequest } from "./globalVariable";
Vue.prototype.GLOBAL = globalVariable;

import { serveDataFormat } from "./serveDataFormat";
import { fileHandle } from "./fileHandle";

const baseURL = "";

const api = axios.create({
    baseURL,
    timeout: 120000,
});
const vm = new Vue();

// 请求拦截
api.interceptors.request.use(
    (config) => {
        let { data, params, customizeRequestConfig = {} } = config;
        let { isEnumFormat = true } = customizeRequestConfig;
        if (isEnumFormat) {
            config.data = serveDataFormat.enumFormat(data);
            config.params = serveDataFormat.enumFormat(params);
        }
        return config;
    },
    (err) => {
        return Promise.reject(err);
    }
);

// 响应拦截
let resultNum = 0;
api.interceptors.response.use(
    async (res) => {
        //falls within the range of 2xx
        let {
            request: { response },
            headers,
            config: { url, customizeResponseConfig = {} },
        } = res;

        if (ifGlobalConfigRequest(url)) {
            //外部组件请求处理
            res.body = res.data;
            return res;
        } else {
            //系统内请求处理
            let {
                defaultFileAction = "none",
                downloadFileName,
                isSimpleServeData = true,
                isJsonFormat = true,
                isAutoSolveError = true,
            } = customizeResponseConfig;

            let checkResponseType;
            switch (Object.prototype.toString.call(response)) {
                case "[object Blob]":
                    try {
                        let blobText = await response.text();
                        JSON.parse(blobText);
                        checkResponseType = "JSON";
                        response = blobText;
                    } catch {
                        checkResponseType = "File";
                    }

                    break;
                case "[object ArrayBuffer]":
                    try {
                        let blobText = await new Blob([response]).text();
                        JSON.parse(blobText);
                        checkResponseType = "JSON";
                        response = blobText;
                    } catch {
                        checkResponseType = "File";
                    }
                    break;
                case "[object String]":
                    checkResponseType = "String";
                    break;
            }

            switch (checkResponseType) {
                case "File":
                    if (defaultFileAction === "none") {
                        return response;
                    } else {
                        return fileHandle(
                            response,
                            defaultFileAction,
                            headers,
                            downloadFileName
                        );
                    }

                case "String":
                case "JSON":
                    try {
                        response = JSON.parse(response);

                        response.data = isJsonFormat
                            ? serveDataFormat.jsonFormat(response.data)
                            : response.data;

                        let { code, message, data } = response;

                        let returnResult = isSimpleServeData ? data : response;
                        if (isAutoSolveError) {
                            switch (code) {
                                case "200":
                                    return returnResult;
                                case "01100":
                                    resultNum++;
                                    break;
                                default:
                                    vm.$alert(message, {
                                        customClass: "my-mes-cls",
                                    });
                                    return Promise.reject(message);
                            }
                            if (resultNum >= 1) {
                                if (
                                    resultNum > 1 &&
                                    router.currentRoute.name === "login"
                                )
                                    return Promise.reject(message);
                                router.replace("/login");
                                vm.$alert(message, {
                                    showClose: false,
                                    callback() {
                                        resultNum = 0;
                                    },
                                });
                                return Promise.reject(message);
                            }
                        } else {
                            return returnResult;
                        }
                    } catch (err) {
                        vm.$alert("网络异常,请稍后再试");
                        console.log(
                            res && JSON.stringify(res),
                            "JSON 解析失败,请检查"
                        );
                        return Promise.reject(err);
                    }
            }
        }
    },
    (err) => {
        //falls out of the range of 2xx
        //let {response,request,message} = err
        let { config, response } = err;

        if (!response) {
            err.message = "网络异常，请稍后再试";
        }
        ifGlobalConfigRequest(config.url) || vm.$alert(err.message);

        return Promise.reject(err);
    }
);

Vue.prototype.$http = api;
export default api;
/**
 *  可以加入以下函数实现对文件下载进度的监听             
    onDownloadProgress(progress) {
        console.log(progress);
        console.log(
            Math.round(
                (progress.loaded / progress.total) * 100
            ) + "%"
        );
    },
 */
